//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "InvoiceBridge.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

TInvoice :: TInvoice()
{
   id = NO_ID;
   paymentType = new TPaymentType();
}

TInvoice :: TInvoice( TInvoice* other)
{
   id         = other->id;
   date       = other->date;
   page       = other->page;
   invoiceID  = other->invoiceID;
   amount     = other->amount;
   paymentType = new TPaymentType(other->paymentType);
   isCanceled = other->isCanceled;
}

__fastcall TInvoice::~TInvoice()
{
   delete paymentType;
}

bool TInvoice :: IsEqual( TInvoice* other)
{
   return (( date == other->date) && ( page == other->page) && ( invoiceID == other->invoiceID));
}

//-------------------------- Invoice Bridge ----------------------------------

TInvoiceBridge :: TInvoiceBridge( TDatabase * database)
{
   sequence = new TSequence( database);

   qryExists = new TQuery( NULL);
   qryExists->DatabaseName = database->DatabaseName;
   BuildExistsQuery();

   qryGet = new TQuery( NULL);
   qryGet->DatabaseName = database->DatabaseName;
   BuildGetQuery();

   qryAdd = new TQuery( NULL);
   qryAdd->DatabaseName = database->DatabaseName;
   BuildAddQuery();

   qryUpdate = new TQuery( NULL);
   qryUpdate->DatabaseName = database->DatabaseName;
   BuildUpdateQuery();

   qryDelete = new TQuery( NULL);
   qryDelete->DatabaseName = database->DatabaseName;
   BuildDeleteQuery();

   qryCancel = new TQuery( NULL);
   qryCancel->DatabaseName = database->DatabaseName;
   BuildCancelQuery();

   qryGetInvoices = new TQuery( NULL);
   qryGetInvoices->DatabaseName = database->DatabaseName;
   BuildGetInvoicesQuery();

   qryGetPageInvoices = new TQuery( NULL);
   qryGetPageInvoices->DatabaseName = database->DatabaseName;
   BuildGetPageInvoicesQuery();
}

TInvoiceBridge :: ~TInvoiceBridge()
{
   delete qryGetPageInvoices;
   delete qryGetInvoices;
   delete qryCancel;
   delete qryDelete;
   delete qryUpdate;
   delete qryAdd;
   delete qryGet;
   delete qryExists;
   delete sequence;
}

void TInvoiceBridge :: BuildExistsQuery()
{
   qryExists->SQL->Add( "SELECT * FROM INVOICES");
   qryExists->SQL->Add( "WHERE ( PAGEID = :prmPageID) AND ( INVOICEID = :prmInvoiceID)");
}

void TInvoiceBridge :: BuildGetQuery()
{
   qryGet->SQL->Add( "SELECT INVOICES.ID, INVOICES.PAGEID, INVOICES.INVOICEID, INVOICES.AMOUNT, INVOICES.PAYMENTTYPE, INVOICES.CREATIONDATE, INVOICES.CANCELED, PAYMENTTYPES.DESCRIPTION FROM INVOICES, PAYMENTTYPES");
   qryGet->SQL->Add( "WHERE (INVOICES.ID = :prmID) AND (INVOICES.PAYMENTTYPE = PAYMENTTYPES.ID)");
}

void TInvoiceBridge :: BuildAddQuery()
{
   qryAdd->SQL->Add( "INSERT INTO INVOICES VALUES ( :prmID, :prmPage, :prmInvoiceID, :prmAmount, :prmDate, :prmCanceled, :prmPaymentType)");
}

void TInvoiceBridge :: BuildUpdateQuery()
{
   qryUpdate->SQL->Add( "UPDATE INVOICES");
   qryUpdate->SQL->Add( "SET PAGEID = :prmPageID,");
   qryUpdate->SQL->Add( "INVOICEID = :prmInvoiceID,");
   qryUpdate->SQL->Add( "AMOUNT = :prmAmount,");
   qryUpdate->SQL->Add( "PAYMENTTYPE = :prmPaymentType,");
   qryUpdate->SQL->Add( "CREATIONDATE = :prmCreationDate,");
   qryUpdate->SQL->Add( "CANCELED = :prmCanceled");
   qryUpdate->SQL->Add( "WHERE");
   qryUpdate->SQL->Add( "ID = :prmID");
}

void TInvoiceBridge :: BuildDeleteQuery()
{
   qryDelete->SQL->Add( "DELETE FROM INVOICES WHERE ID = :prmID");
}

void TInvoiceBridge :: BuildCancelQuery()
{
   qryCancel->SQL->Add( "UPDATE INVOICES");
   qryCancel->SQL->Add( "SET CANCELED = 'Y'");
   qryCancel->SQL->Add( "WHERE ID = :prmID");     
}

void TInvoiceBridge :: BuildGetInvoicesQuery()
{
   qryGetInvoices->SQL->Add( "SELECT INVOICES.ID, INVOICES.PAGEID, INVOICES.INVOICEID, INVOICES.AMOUNT, INVOICES.PAYMENTTYPE, INVOICES.CREATIONDATE, INVOICES.CANCELED, PAYMENTTYPES.DESCRIPTION FROM INVOICES, PAYMENTTYPES");
   qryGetInvoices->SQL->Add( "WHERE INVOICES.PAYMENTTYPE = PAYMENTTYPES.ID");
   qryGetInvoices->SQL->Add( "ORDER BY CREATIONDATE DESC, PAGEID DESC, INVOICEID DESC");
}

void TInvoiceBridge :: BuildGetPageInvoicesQuery()
{
   qryGetPageInvoices->SQL->Add( "SELECT INVOICES.ID, INVOICES.PAGEID, INVOICES.INVOICEID, INVOICES.AMOUNT, INVOICES.PAYMENTTYPE, INVOICES.CREATIONDATE, INVOICES.CANCELED, PAYMENTTYPES.DESCRIPTION FROM INVOICES, PAYMENTTYPES");
   qryGetPageInvoices->SQL->Add( "WHERE ( PAGEID = :prmPage) AND (INVOICES.PAYMENTTYPE = PAYMENTTYPES.ID)");
}

__int64 TInvoiceBridge :: GetLastID()
{
   return sequence->GetLastValue( "INVOICES");
}

__int64 TInvoiceBridge :: GetNextID()
{
   return sequence->GetNextValue( "INVOICES");
}

void SetInvoice( TQuery* query, TInvoice* invoice)
{
   invoice->id         = query->FieldByName( "ID")->AsInteger;
   invoice->page       = query->FieldByName( "PAGEID")->AsInteger;
   invoice->invoiceID  = query->FieldByName( "INVOICEID")->AsInteger;
   invoice->amount     = ( double)query->FieldByName( "AMOUNT")->AsCurrency;
   invoice->paymentType->id = query->FieldByName( "PAYMENTTYPE")->AsInteger;
   invoice->paymentType->description = query->FieldByName( "DESCRIPTION")->AsString;
   invoice->date       = query->FieldByName( "CREATIONDATE")->AsDateTime;
   invoice->isCanceled = TStringUtilites::YNToBoolean( query->FieldByName( "CANCELED")->AsString);
}

bool TInvoiceBridge :: IsExist( __int64 pageID, __int64 invoiceID)
{
   bool result = false;

   qryExists->ParamByName( "prmPageID")->AsInteger        = pageID;
   qryExists->ParamByName( "prmInvoiceID")->AsInteger     = invoiceID;

   qryExists->Open();

   try
   {
      result = ( !qryExists->IsEmpty());
   }
   __finally
   {
      qryExists->Close();
   }//try-finally

   return result;
}

void TInvoiceBridge :: Get( __int64 id, TInvoice* invoice)
{
   qryGet->ParamByName( "prmID")->AsInteger = id;

   qryGet->Open();

   try
   {
      SetInvoice( qryGet, invoice);
   }
   __finally
   {
      qryGet->Close();
   }
}

void TInvoiceBridge :: GetInvoices( TStrings * invoices)
{
   TInvoice * invoice;
   
   qryGetInvoices->Open();

   try
   {
      for( int i = 0; i < invoices->Count; i++)
         delete invoices->Objects[ i];
      invoices->Clear();

      qryGetInvoices->First();

      while ( !qryGetInvoices->Eof)
      {
         invoice = new TInvoice();
         SetInvoice( qryGetInvoices, invoice);

         invoices->AddObject( IntToStr( invoice->id), invoice);
         qryGetInvoices->Next();
      }
   }
   __finally
   {
      qryGetInvoices->Close();
   }
}

void TInvoiceBridge :: GetPageInvoices( __int64 pageID, TStrings * invoices)
{
   TInvoice * invoice;

   qryGetPageInvoices->ParamByName( "prmPage")->AsInteger  = pageID;
   qryGetPageInvoices->Open();

   try
   {
      qryGetPageInvoices->First();

      while ( !qryGetPageInvoices->Eof)
      {
         invoice = new TInvoice();
         SetInvoice( qryGetPageInvoices, invoice);
         invoices->AddObject( IntToStr( invoice->invoiceID), invoice);
         qryGetPageInvoices->Next();
      }//while
   }
   __finally
   {
      qryGetPageInvoices->Close();
   }//try-finally
}

void TInvoiceBridge :: Add( __int64 id, TInvoice* invoice)
{
   qryAdd->ParamByName( "prmID")->AsInteger = id;
   qryAdd->ParamByName( "prmPage")->AsInteger = invoice->page;
   qryAdd->ParamByName( "prmInvoiceID")->AsInteger = invoice->invoiceID;
   qryAdd->ParamByName( "prmAmount")->AsCurrency = invoice->amount;
   qryAdd->ParamByName( "prmPaymentType")->AsInteger = invoice->paymentType->id;
   qryAdd->ParamByName( "prmDate")->AsDateTime = invoice->date;
   qryAdd->ParamByName( "prmCanceled")->AsString = TStringUtilites::BooleanToYN( invoice->isCanceled);

   qryAdd->ExecSQL();
}

void TInvoiceBridge :: Update( __int64 id, TInvoice* invoice)
{
   qryUpdate->ParamByName( "prmID")->AsInteger = invoice->id;
   qryUpdate->ParamByName( "prmPageID")->AsInteger = invoice->page;
   qryUpdate->ParamByName( "prmInvoiceID")->AsInteger = invoice->invoiceID;
   qryUpdate->ParamByName( "prmAmount")->AsCurrency = invoice->amount;
   qryUpdate->ParamByName( "prmPaymentType")->AsInteger = invoice->paymentType->id;
   qryUpdate->ParamByName( "prmCreationDate")->AsDateTime = invoice->date;
   qryUpdate->ParamByName( "prmCanceled")->AsString = TStringUtilites::BooleanToYN( invoice->isCanceled);

   qryUpdate->ExecSQL();
}

void TInvoiceBridge :: Delete( __int64 id)
{
   qryDelete->ParamByName( "prmID")->AsInteger = id;
   qryDelete->ExecSQL();
}

void TInvoiceBridge :: Cancel( __int64 id)
{
   qryCancel->ParamByName( "prmID")->AsInteger = id;
   qryCancel->ExecSQL();
}
